package com.huan.es8.script;

import co.elastic.clients.elasticsearch._types.ScriptSortType;
import co.elastic.clients.elasticsearch._types.SortOrder;
import co.elastic.clients.elasticsearch._types.mapping.IntegerNumberProperty;
import co.elastic.clients.elasticsearch._types.mapping.KeywordProperty;
import co.elastic.clients.elasticsearch._types.mapping.LongNumberProperty;
import co.elastic.clients.elasticsearch._types.mapping.Property;
import co.elastic.clients.elasticsearch.core.SearchRequest;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.json.JsonData;
import com.huan.es8.AbstractEs8Api;
import org.junit.jupiter.api.*;

import java.io.IOException;
import java.util.Arrays;

/**
 * 脚本排序，固定的某个值的数据排在前面，其余的数据按照别的字段排序<br/>
 * <a href="https://www.elastic.co/guide/en/elasticsearch/reference/7.17/sort-search-results.html">官方文档</a>
 * <a href="https://blog.csdn.net/fu_huo_1993/article/details/128606146">博客地址</a>
 *
 * @author huan.fu
 * @date 2023/1/12 - 12:22
 */
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class ScriptFieldSort extends AbstractEs8Api {

    @BeforeAll
    public void createIndex() throws IOException {
        client.indices()
                .create(indexRequest ->
                        indexRequest.index("index_person")
                                .mappings(mappings ->
                                        mappings.properties("id", new Property(new LongNumberProperty.Builder().build()))
                                                .properties("name", new Property(new KeywordProperty.Builder().build()))
                                                .properties("age", new Property(new IntegerNumberProperty.Builder().build()))
                                                .properties("province", new Property(new KeywordProperty.Builder().build()))
                                )
                );
        bulk("index_person", Arrays.asList(
                "{\"id\":1, \"name\":\"张三\",\"age\":18,\"province\":\"湖北\"}",
                "{\"id\":2, \"name\":\"李四\",\"age\":19,\"province\":\"湖北\"}",
                "{\"id\":3, \"name\":\"王武\",\"age\":20,\"province\":\"西安\"}",
                "{\"id\":4, \"name\":\"赵六\",\"age\":21,\"province\":\"西安\"}",
                "{\"id\":5, \"name\":\"钱七\",\"age\":22,\"province\":\"上海\"}"
        ));
    }

    @Test
    @DisplayName("脚本排序，固定的某个值的数据排在前面，其余的数据按照别的字段排序")
    public void test01() throws IOException {
        SearchRequest request = SearchRequest.of(searchRequest ->
                searchRequest.index("index_person")
                        .query(query -> query.matchAll(matchAll -> matchAll))
                        .size(100)
                        .sort(sort ->
                                sort.script(sortScript ->
                                        sortScript.type(ScriptSortType.Number)
                                                .order(SortOrder.Desc)
                                                .script(script ->
                                                        script.inline(inline ->
                                                                inline.source("if(params['_source']['province'] == params.province){\n" +
                                                                                "                        1\n" +
                                                                                "                      } else {\n" +
                                                                                "                        0\n" +
                                                                                "                      }")
                                                                        .params("province", JsonData.of("湖北"))
                                                        )
                                                )
                                )
                        )
                        .sort(sort ->
                                sort.field(field ->
                                        field.field("province").order(SortOrder.Asc)
                                )
                        )
                        .sort(sort ->
                                sort.field(field ->
                                        field.field("age").order(SortOrder.Desc).missing("_last")
                                )
                        )
        );

        System.out.println("request: " + request);
        SearchResponse<Object> response = client.search(request, Object.class);
        System.out.println("response: " + response);
    }

    @AfterAll
    public void deleteIndex() throws IOException {
        deleteIndex("index_person");
    }
}
